package com.kexilo.config.utils;

import com.kexilo.core.common.utils.StringUtils;
import com.kexilo.core.common.utils.spring.SpringUtils;
import com.kexilo.config.service.ConfigService;
import com.kexilo.config.domain.ConfigData;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Collection;
import java.util.List;

/**
 * 参数配置工具类 - config插件版本
 * 作为config插件的一部分，提供配置相关的工具方法
 * 
 * @author Kexilo
 */
@SuppressWarnings(value = { "unchecked", "rawtypes" })
public class ConfigUtils {
    
    /**
     * 参数管理 cache key
     */
    public static final String SYS_CONFIG_KEY = "sys_config:";

    /**
     * 设置cache key
     * 
     * @param configKey 参数键
     * @param configValue 参数值
     */
    public static void setConfigCache(String configKey, String configValue) {
        try {
            RedisTemplate redisTemplate = SpringUtils.getBean(RedisTemplate.class);
            redisTemplate.opsForValue().set(getCacheKey(configKey), configValue);
        } catch (Exception e) {
            // Redis不可用时忽略缓存操作
        }
    }

    /**
     * 获取cache key
     * 
     * @param configKey 参数键
     * @return 缓存键key
     */
    public static String getCacheKey(String configKey) {
        return SYS_CONFIG_KEY + configKey;
    }

    /**
     * 获取参数配置
     * 
     * @param configKey 参数键
     * @return 参数值
     */
    public static String getConfigValue(String configKey) {
        // 先从缓存获取
        String configValue = getConfigFromCache(configKey);
        if (StringUtils.isNotEmpty(configValue)) {
            return configValue;
        }
        
        // 缓存中没有，从服务获取
        String value = null;
        try {
            ConfigService configService = SpringUtils.getBean(ConfigService.class);
            ConfigData configData = configService.getConfigData(configKey);
            if (configData != null && StringUtils.isNotEmpty(configData.getConfigValue())) {
                value = configData.getConfigValue();
                // 更新缓存
                setConfigCache(configKey, value);
            }
        } catch (Exception e) {
            // 如果没有找到ConfigService实现，返回null
            // 这样可以保证插件独立运行
        }
        
        return value;
    }
    
    /**
     * 从缓存获取配置值
     * 
     * @param configKey 参数键
     * @return 参数值
     */
    private static String getConfigFromCache(String configKey) {
        try {
            RedisTemplate redisTemplate = SpringUtils.getBean(RedisTemplate.class);
            return (String) redisTemplate.opsForValue().get(getCacheKey(configKey));
        } catch (Exception e) {
            // Redis不可用时返回null
            return null;
        }
    }

    /**
     * 获取参数配置（转换为整数类型）
     * 
     * @param configKey 参数键
     * @return 参数值
     */
    public static Integer getConfigIntValue(String configKey) {
        String configValue = getConfigValue(configKey);
        if (StringUtils.isNotEmpty(configValue)) {
            try {
                return Integer.valueOf(configValue);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }

    /**
     * 获取参数配置（转换为布尔类型）
     * 
     * @param configKey 参数键
     * @return 参数值
     */
    public static Boolean getConfigBoolValue(String configKey) {
        String configValue = getConfigValue(configKey);
        if (StringUtils.isNotEmpty(configValue)) {
            // 支持多种布尔值表示
            String lowerValue = configValue.toLowerCase();
            return "true".equals(lowerValue) || "1".equals(lowerValue) || 
                   "yes".equals(lowerValue) || "on".equals(lowerValue);
        }
        return null;
    }
    
    /**
     * 获取参数配置（转换为长整型）
     * 
     * @param configKey 参数键
     * @return 参数值
     */
    public static Long getConfigLongValue(String configKey) {
        String configValue = getConfigValue(configKey);
        if (StringUtils.isNotEmpty(configValue)) {
            try {
                return Long.valueOf(configValue);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }
    
    /**
     * 获取参数配置（转换为双精度浮点型）
     * 
     * @param configKey 参数键
     * @return 参数值
     */
    public static Double getConfigDoubleValue(String configKey) {
        String configValue = getConfigValue(configKey);
        if (StringUtils.isNotEmpty(configValue)) {
            try {
                return Double.valueOf(configValue);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }
    
    /**
     * 获取参数配置（如果为空则返回默认值）
     * 
     * @param configKey 参数键
     * @param defaultValue 默认值
     * @return 参数值
     */
    public static String getConfigValue(String configKey, String defaultValue) {
        String value = getConfigValue(configKey);
        return StringUtils.isNotEmpty(value) ? value : defaultValue;
    }
    
    /**
     * 获取参数配置（转换为整数类型，如果为空则返回默认值）
     * 
     * @param configKey 参数键
     * @param defaultValue 默认值
     * @return 参数值
     */
    public static Integer getConfigIntValue(String configKey, Integer defaultValue) {
        Integer value = getConfigIntValue(configKey);
        return value != null ? value : defaultValue;
    }
    
    /**
     * 获取参数配置（转换为布尔类型，如果为空则返回默认值）
     * 
     * @param configKey 参数键
     * @param defaultValue 默认值
     * @return 参数值
     */
    public static Boolean getConfigBoolValue(String configKey, Boolean defaultValue) {
        Boolean value = getConfigBoolValue(configKey);
        return value != null ? value : defaultValue;
    }
    
    /**
     * 检查配置是否存在
     * 
     * @param configKey 参数键
     * @return 是否存在
     */
    public static boolean hasConfig(String configKey) {
        return getConfigValue(configKey) != null;
    }
    
    /**
     * 批量获取配置
     * 
     * @param configKeys 参数键列表
     * @return 配置键值对
     */
    public static java.util.Map<String, String> getConfigValues(List<String> configKeys) {
        java.util.Map<String, String> result = new java.util.HashMap<>();
        if (configKeys != null && !configKeys.isEmpty()) {
            for (String key : configKeys) {
                String value = getConfigValue(key);
                if (value != null) {
                    result.put(key, value);
                }
            }
        }
        return result;
    }

    /**
     * 删除参数缓存
     * 
     * @param configKey 参数键
     */
    public static void removeConfigCache(String configKey) {
        try {
            RedisTemplate redisTemplate = SpringUtils.getBean(RedisTemplate.class);
            redisTemplate.delete(getCacheKey(configKey));
        } catch (Exception e) {
            // Redis不可用时忽略缓存操作
        }
    }

    /**
     * 清空参数缓存
     */
    public static void clearConfigCache() {
        try {
            RedisTemplate redisTemplate = SpringUtils.getBean(RedisTemplate.class);
            Collection<String> keys = redisTemplate.keys(SYS_CONFIG_KEY + "*");
            if (keys != null && !keys.isEmpty()) {
                redisTemplate.delete(keys);
            }
        } catch (Exception e) {
            // Redis不可用时忽略缓存操作
        }
    }
    
    /**
     * 刷新指定配置的缓存
     * 
     * @param configKey 参数键
     */
    public static void refreshConfigCache(String configKey) {
        removeConfigCache(configKey);
        getConfigValue(configKey); // 重新从数据库加载
    }
    
    /**
     * 批量刷新配置缓存
     * 
     * @param configKeys 参数键列表
     */
    public static void refreshConfigCache(List<String> configKeys) {
        if (configKeys != null && !configKeys.isEmpty()) {
            configKeys.forEach(ConfigUtils::refreshConfigCache);
        }
    }
    
    /**
     * 预热配置缓存
     * 
     * @param configKey 参数键
     */
    public static void warmupConfigCache(String configKey) {
        try {
            ConfigService configService = SpringUtils.getBean(ConfigService.class);
            ConfigData configData = configService.getConfigData(configKey);
            if (configData != null && StringUtils.isNotEmpty(configData.getConfigValue())) {
                setConfigCache(configKey, configData.getConfigValue());
            }
        } catch (Exception e) {
            // 预热失败不影响正常功能
        }
    }
    
    /**
     * 批量预热配置缓存
     * 
     * @param configKeys 参数键列表
     */
    public static void warmupConfigCache(List<String> configKeys) {
        if (configKeys != null && !configKeys.isEmpty()) {
            configKeys.forEach(ConfigUtils::warmupConfigCache);
        }
    }
    
    /**
     * 获取所有配置的键
     * 
     * @return 配置键列表
     */
    public static List<String> getAllConfigKeys() {
        try {
            ConfigService configService = SpringUtils.getBean(ConfigService.class);
            List<ConfigData> allConfigs = configService.getAllConfigs();
            if (allConfigs != null && !allConfigs.isEmpty()) {
                return allConfigs.stream()
                    .map(ConfigData::getConfigKey)
                    .collect(java.util.stream.Collectors.toList());
            }
        } catch (Exception e) {
            // 如果没有找到ConfigService实现，返回空列表
        }
        return new java.util.ArrayList<>();
    }
    
    /**
     * 设置配置值（仅缓存，不保存到数据库）
     * 
     * @param configKey 参数键
     * @param configValue 参数值
     */
    public static void setConfigValue(String configKey, String configValue) {
        setConfigCache(configKey, configValue);
    }
    
    /**
     * 批量设置配置值（仅缓存，不保存到数据库）
     * 
     * @param configs 配置键值对
     */
    public static void setConfigValues(java.util.Map<String, String> configs) {
        if (configs != null && !configs.isEmpty()) {
            configs.forEach(ConfigUtils::setConfigValue);
        }
    }
}
